package com.ilink.ilinkcommon.utils;

import com.alibaba.fastjson.JSONObject;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;

@Component
public class HttpUtils {
    @Autowired
    private RestTemplate restTemplate;

/*
 * 发送get请求
 *
 * @param url
 * @param params
 * @return com.alibaba.fastjson.JSONObject
 * @author liuzheng
 * @create 2024-09-10
 **/
    public <T> JSONObject get(String url, Map<String,Object> params) {
        JSONObject result = restTemplate.getForObject(url, JSONObject.class, params);

        if(result == null) {
            throw new RuntimeException("请求网络错误");
        }
        return result;
    }
    public <T> JSONObject get(String url) {
        JSONObject result = restTemplate.getForObject(url, JSONObject.class);

        if(result == null) {
            throw new RuntimeException("请求网络错误");
        }
        return result;
    }

    /**
     * 描述: 以自定义返回形式返回get请求
     * 注意：如果get请求需要传递参数，需要自己写到url中，然后params才会填充到url中，url不携带参数
     * 同时params不能使用泛型，不然getForObject调用的是单个变量，对于传入Map类型的无法解析为全部变量
     */
    public <T> T get(String url, Map<String,Object> params, Class<T> eClass) {
        T result = restTemplate.getForObject(url, eClass, params);

        if(result == null) {
            throw new RuntimeException("请求网络错误");
        }
        return result;
    }

    public <T> T get(String url,  Class<T> eClass) {
        T result = restTemplate.getForObject(url, eClass);

        if(result == null) {
            throw new RuntimeException("请求网络错误");
        }
        return result;
    }


    /**
     * 描述: 传入自定义的headers的post请求，
     * 采用泛型编程，支持多种类型，可以传map也可以传Object
     * note: x-www-form-urlencoded 需要使用MultiValueMap 而不是 HashMap,但如果是json就必须是HashMap，不然提交的是列表数据。get请求同理
     */
    public <T> JSONObject post(String url,T params,HttpHeaders httpHeaders) {
        HttpEntity<T> request = new HttpEntity<>(params,httpHeaders);
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url,request, JSONObject.class);
        if (!response.getStatusCode().is2xxSuccessful()) {
            throw new ResponseStatusException(response.getStatusCode(), "请求出错");
        }
        return response.getBody();
    }

    /**
     * 描述: 不传入headers默认为json格式
     */
    public <T> JSONObject post(String url,T params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        return post(url,params,httpHeaders);
    }

    public <T,E> E post(String url,T params,Class<E> eClass) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        return post(url,params,httpHeaders,eClass);
    }

    /**
     * 描述: 自定义返回格式的post请求，指定headers
     */
    public <T,E> E post(String url,T params,HttpHeaders httpHeaders,Class<E> eClass) {
        HttpEntity<T> request = new HttpEntity<>(params,httpHeaders);
        ResponseEntity<E> response = restTemplate.postForEntity(url,request, eClass);
        // 如果是 检测是否是20x，否则是失败
        if (!response.getStatusCode().is2xxSuccessful()) {
            throw new ResponseStatusException(response.getStatusCode(), "请求出错");
        }

        return response.getBody();
    }


}
